package com.light.mytext.mycustomview

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.FrameLayout
import com.light.mytext.R
import kotlin.math.abs
import kotlin.math.floor

class LineView2(context: Context?, width: Int) :
    View(context), View.OnTouchListener {
    var mStartX = 0f
    var mStartY = 0f
    var mEndX = 0f
    var mEndY = 0f
    var mPaint: Paint? = null

    var lineHeight = 5
    var aViewWidth = 0
    var aViewHeight = 0
    var moveX = 0
    var moveY = 0
    var downRawX = 0f
    var downRawY = 0f

    var screenWidth = 0
    var screenHeight = 0
    var offsetX = 0f
    var offsetY = 0f

    var direction = "Center"

    //线性公式相关
    var line_k = 0f
    var line_b = 0f

    var isCanMove = false

    init {
        initPaint()
    }

    fun initPaint() {
        mPaint = Paint()
        mPaint!!.isAntiAlias = true//设置画笔抗锯齿
        mPaint!!.style = Paint.Style.STROKE//设置画笔样式
        mPaint!!.color = Color.WHITE
        mPaint!!.strokeWidth = 15f
        setOnTouchListener(this)
        initScreenW_H()
        getLine()
    }

    /**
     * 初始化获取屏幕宽高
     */
    protected fun initScreenW_H() {
        screenHeight = resources.displayMetrics.heightPixels
        screenWidth = resources.displayMetrics.widthPixels
        aViewWidth = screenWidth
        aViewHeight = screenHeight
        /* aViewWidth = screenWidth - 20
         aViewHeight = 60*/
    }

    override fun draw(canvas: Canvas?) {
        super.draw(canvas)
        canvas!!.drawLine(mStartX, mStartY, mEndX, mEndY, mPaint!!)
        getLine()
    }


    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
        if (event!!.action == MotionEvent.ACTION_DOWN) {
            downRawX = event!!.rawX
            downRawY = event.rawY
            moveX = event.x.toInt()
            moveY = event.y.toInt()//getX/Y()不适用于绑定在动态组件上的onTouchListener。会出现抖动
            direction = getDirection(downRawX, downRawY)
            Log.i("LineView==Down-->", "downRawX==" + downRawX + "downRawY==" + downRawY)
            isCanMove = isOnLine(downRawX, downRawY)//触摸点是否在线上，即是否满足拖动条件
        }
        Log.i("LineView==isOnLine-->", getDirection(downRawX, downRawY))
        if (isCanMove) {
            Choose()
            handleEvent(event, v!!)
            invalidate()//使用此方法来重绘
        }
        return true
    }


    /**
     * 处理事件
     * onTouch直接使用getX()和getY()会引起抖动 可使用差值或者rawX和rawY
     * onTouch直接使用v.layout 也会引起抖动，可直接使用layout
     * */
    fun handleEvent(event: MotionEvent?, v: View) {
        when (event!!.action) {
            MotionEvent.ACTION_MOVE -> {
                //计算移动的距离
                offsetX = event.rawX.toInt() - downRawX
                offsetY = event.rawY.toInt() - downRawY

                when (direction) {
                    "Center" -> {
                        Center_Draw(v, offsetX, offsetY)
                    }
                    "Left" -> {
                        mStartX = event.rawX
                        mStartY = event.rawY

                    }
                    "Right" -> {
                        mEndX = event.rawX
                        mEndY = event.rawY
                    }
                }
                //记得在这里要重置数据  忘记的话重绘时候会一直闪烁
                downRawX = event.rawX
                downRawY = event.rawY
                /* if (direction != "Center") {
                  v!!.layout(
                      if (mStartX < mEndX) mStartX.toInt() else mEndX.toInt(),
                      if (mStartY < mEndY) mStartY.toInt() else mEndY.toInt(),
                      if (mStartX < mEndX) mEndX.toInt() else mStartX.toInt(),
                      if (mStartY < mEndY) mEndY.toInt() else mStartY.toInt()
                  )
                  val params: FrameLayout.LayoutParams = layoutParams as FrameLayout.LayoutParams
                  params.leftMargin = if (mStartX < mEndX) mStartX.toInt() else mEndX.toInt()
                  params.topMargin = if (mStartY < mEndY) mStartY.toInt() else mEndY.toInt()
                  layoutParams = params
              }*/
                Log.i(
                    "LineView==",
                    "ACTION_MOVE()-->mStartX==" + mStartX + "mStartY==" + mStartY + "mEndX==" + mEndX + "mEndY==" + mEndY
                )
                /*Log.i(
                    "LineView==",
                    "l==" + (if (mStartX < mEndX) mStartX.toInt() else mEndX.toInt()) + "t==" + (if (mStartY < mEndY) mStartY.toInt() else mEndY.toInt())
                            + "r==" + (if (mStartX < mEndX) mEndX.toInt() else mStartX.toInt()) + "b==" + (if (mStartY < mEndY) mEndY.toInt() else mStartY.toInt())
                )*/
            }
            MotionEvent.ACTION_UP -> {
                cancelChoose()
            }
        }
    }

    fun Center_Draw(v: View, dRx: Float, dRy: Float) {
        mStartX += dRx
        mStartY += dRy
        mEndX += dRx
        mEndY += dRy
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        setMeasuredDimension(
            aViewWidth,//屏幕宽
            aViewHeight
        )
        Log.i(
            "LineView==",
            "onMeasure()-->aViewWidth==" + aViewWidth + "aViewHeight==" + aViewHeight
        )
        Log.i(
            "LineView==",
            "onMeasure()-->left==" + left + "right==" + right
        )
        if (mStartX == 0f && mStartY == 0f && mEndX == 0f && mEndY == 0f) {
            getInitialXY()
        }
    }

    /**
     * 以下两个方法设置View居中画布显示
     * 执行顺序（1）onMeasure（2）onSizeChanged
     */
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
//        aViewWidth = measuredWidth
//        aViewHeight = measuredHeight//之前写错成h   会出现负值
        /* Log.i(
             "LineView==",
             "onSizeChanged()-->aViewWidth==" + aViewWidth + "aViewHeight==" + aViewHeight
         )*/
        Log.i(
            "LineView==",
            "onSizeChanged()-->left==" + left + "right==" + right
        )

    }


    /**
     * 设置View相关参数
     */
    fun setViewMess() {
        mStartX = left.toFloat()
        mStartY = top.toFloat() + lineHeight
        mEndX = right.toFloat()
        mEndY = top.toFloat() + lineHeight
    }

    /**
     * 取消选中
     */
    fun cancelChoose() {
        //重置选中paint
        mPaint!!.reset()
        //把画笔颜色设置为透明，重绘
        mPaint!!.color = Color.WHITE
        mPaint!!.isAntiAlias = true//设置画笔抗锯齿
        mPaint!!.style = Paint.Style.STROKE//设置画笔样式
        mPaint!!.strokeWidth = 2f
        invalidate()
    }

    /**
     * 选中
     */
    fun Choose() {
        //重置选中paint
        mPaint!!.reset()
        //把画笔颜色设置为透明，重绘
        mPaint!!.color = resources.getColor(R.color.tv_color_00)
        mPaint!!.isAntiAlias = true//设置画笔抗锯齿
        mPaint!!.style = Paint.Style.STROKE//设置画笔样式
        mPaint!!.strokeWidth = 2f
        invalidate()
    }


    /**
     * 在view上随机获取初始直线的坐标
     */
    fun getInitialXY() {
        mStartX = 0.toFloat()
        mStartY = random(0, aViewHeight).toFloat()
        mEndX = aViewWidth.toFloat()
        mEndY = random(0, aViewHeight).toFloat()
    }

    /**
     * 获取上下限均包含的随机数
     */
    fun random(min: Int, max: Int): Double {
        return floor(Math.random() * (max - min + 1)) + min
    }

    /**
     * 由两点确定直线(mStartX,mStartY)、(mEndX,mEndY)
     * y=k*x+b
     * k=﹙y1－y2﹚／﹙x1－x2﹚
     * b=﹙y2x1－y1x2﹚／﹙x1－x2﹚
     */

    fun getLine() {
        line_k = (mEndY - mStartY) / (mEndX - mStartX)
        line_b = (mEndY * mStartX - mStartY * mEndX) / (mStartX - mEndX)
        Log.i(
            "LineView==getLine()",
            "y==" + line_k + "*x+" + line_b
        )
    }

    /**
     * 判断触摸点是否在直线上
     * 20是设置的扩大范围值，防止线过细，不容易触摸到
     */
    fun isOnLine(xm: Float, ym: Float): Boolean {
//        return ym == (line_k * xm + line_b)
        return ym in (line_k * xm + line_b - 20)..(line_k * xm + line_b) + 20
    }

    /**
     * 判断触摸点在直线上哪个位置 两端的话 重绘端点  中间的话平移
     */
    fun getDirection(dx: Float, dy: Float): String {
        var direction = "Center"
        var point1 = 0f
        var point2 = 0f
        if (mStartY <= mEndY) {
            point1 = mStartY + (mEndY - mStartY) * 0.2.toFloat()
            point2 = mStartY + (mEndY - mStartY) * 0.8.toFloat()
        } else {
            point1 = mStartY - ((mStartY - mEndY) * 0.2.toFloat())
            point2 = mStartY - ((mStartY - mEndY) * 0.8.toFloat())
        }

        Log.i(
            "LineView==getDirection",
            "mStartY==" + mStartY + "mEndY==" + mEndY+"point1=="+point1+"point2=="+point2
        )
        if (!isOnLine(dx, dy)) {
            return "触摸点不在线上"
        } else {
            if (dy in mStartY.coerceAtMost(point1)..mStartY.coerceAtLeast(point1)) {
                direction = "Left"
            }
            if (dy in point1.coerceAtMost(point2)..point1.coerceAtLeast(point2)) {
                direction = "Center"
            }
            if (dy in mEndY.coerceAtMost(point2)..mEndY.coerceAtLeast(point2)) {
                direction = "Right"
            }
        }
        return direction
    }


}